package com.ndp.fb.walle.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.ndp.fb.constant.CommonConstants;
import com.ndp.fb.enums.ErrorType;
import com.ndp.fb.model.business.vo.cache.result.EntrustAccountVo;
import com.ndp.fb.rdb.model.EntrustAccountExt;
import com.ndp.fb.rdb.model.Pager;
import com.ndp.fb.rdb.model.User;
import com.ndp.fb.rdb.model.adpublishcondition.AdPublishCondition;
import com.ndp.fb.rdb.model.adpublishcondition.AdPublishConditionResult;
import com.ndp.fb.redis.api.RedisClient;
import com.ndp.fb.util.DateUtil;
import com.ndp.fb.util.ListUtil;
import com.ndp.fb.util.StringUtil;
import com.ndp.fb.walle.business.AdPublishConditionService;
import com.ndp.fb.walle.business.BusinessManagerService;
import com.ndp.fb.walle.business.EntrustAccountService;
import com.ndp.fb.model.business.vo.BaseVoParam;
import com.ndp.fb.walle.model.vo.OutputResult;
import com.ndp.fb.walle.model.vo.PageResult;
import com.ndp.fb.walle.model.vo.adpublishcondition.param.AccountFromConnParam;
import com.ndp.fb.walle.model.vo.adpublishcondition.param.AdPublishConditionDetailParam;
import com.ndp.fb.walle.model.vo.adpublishcondition.param.SearchListParam;
import com.ndp.fb.walle.model.vo.adpublishcondition.param.UpdateStatusParam;
import com.ndp.fb.walle.model.vo.adpublishcondition.result.AdPublishConditionDetailResult;
import com.ndp.fb.walle.util.ResponseUtils;

/**
 * Created by Evan on 2015/3/24 10:51.
 */
@RequestMapping("/adpublishcondition")
@Controller
public class AdPublishConditionController {
    private static final Logger logger = LoggerFactory.getLogger(AdPublishConditionController.class);
    @Autowired
    BusinessManagerService businessManagerService;
    @Autowired
    private RedisClient redisClient;
    @Autowired
    private EntrustAccountService entrustAccountService;
    @Autowired
    private AdPublishConditionService adPublishConditionService;


    /**
     * @description 页面信息查找
     * @author Evan
     * 创建时间 2015年3月24日 上午10:38:55
     */
    @RequestMapping(value = "search")
    @ResponseBody
    public ResponseEntity<String> search(@RequestParam(value = "param", required = true) String param, HttpServletRequest httpServletRequest) {
        logger.info("AdPublishConditionController search() begin.");
        ErrorType errorType = null;
        Map<String, Object> data = null;
        try {
            User user = (User) httpServletRequest.getSession().getAttribute("user");
            String userId = user.getTicket();
            SearchListParam searchListParam = JSON.parseObject(param, SearchListParam.class);
            //查询列表
            Integer sizeNo = searchListParam.getPSize() == null ? CommonConstants.DEFAULT_PAGE_SIZE_100 : searchListParam.getPSize();
            Integer firstResult = searchListParam.getCPage() == null ? 0 : (searchListParam.getCPage() - 1) * sizeNo;
            Pager<AdPublishConditionResult> results = adPublishConditionService.findAdPublishConditionWithPager(userId, searchListParam.getSearchName(), user.getOrgId(), firstResult, sizeNo);
            if(results==null){
            	results = new Pager<>();
            	results.setPageIndex(sizeNo);
            	results.setTotalSize(0L);
            }
            // 计算分页结果
            long tSize = results.getTotalSize();
            float nrOfPages = (float) tSize / sizeNo;
            int tPage = (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages);
            PageResult pageResult = new PageResult(tPage, searchListParam.getCPage(), searchListParam.getPSize(), tSize);
            // 封装响应结果
            data = new HashMap<>();
            List<AdPublishConditionResult> adPublishConditionResults = new ArrayList<>();
            if(ListUtil.isNotEmpty(results.getResultList())) {
                for(AdPublishConditionResult adPublishConditionResult : results.getResultList()) {
                    String time = adPublishConditionResult.getOperationTime();
                    if(StringUtil.isNotEmpty(time))
                    {
                        adPublishConditionResult.setOperationTime(DateUtil.parserDateToStr(new Date(Long.parseLong(time)), CommonConstants.DATE_FORMAT_YYYYMMDDHHMMSS, user.getTimezoneId()));
                    }
                    adPublishConditionResults.add(adPublishConditionResult);
                }
            }
            data.put("conditions", adPublishConditionResults);
            data.put("paginator", pageResult);
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("AdPublishConditionController search() end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSON(outputResult).toString());
    }


	/**
	 * 根据应用id获取账户
	 */
	@RequestMapping(value = "loadDetail")
	@ResponseBody
	public ResponseEntity<String> loadDetail(@RequestParam(value = "param", required = true) String param,
			HttpServletRequest httpServletRequest) {
		logger.info("AdPublishConditionController loadDetail() begin.");
		ErrorType errorType = null;
		AdPublishConditionDetailResult data = null;
		try {
			User user = (User) httpServletRequest.getSession().getAttribute("user");

			// String adminUserId = null;
			// List<Long> roleIds = userService.getRoleByUser(user.getId());
			// if (ListUtil.isNotEmpty(roleIds) &&
			// (roleIds.contains(CommonConstants.ROLE_UIDESIGNER) ||
			// roleIds.contains(CommonConstants.ROLE_OUTERUIDESIGNER))) {
			// //如果是美宣或外部设计师
			// User adminUser =
			// userService.getAdminUserByCurrentUser(user.getTicket());
			// adminUserId = adminUser !=null?adminUser.getTicket():"-1";
			// } else {
			// adminUserId = user.getTicket();
			// }

			BaseVoParam par = JSON.parseObject(param, BaseVoParam.class);
			data = adPublishConditionService.getAdPublishConditionDetailResult(par.getId());
		} catch (Exception e) {
			errorType = ErrorType.INTERNAL_EXCEPTION;
			logger.error(e.getMessage(), e);
		}
		OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
		logger.info("AdPublishConditionController loadDetail() end.");
		return ResponseUtils.returnJsonWithUTF8(JSON.toJSON(outputResult).toString());
	}


    /**
     * 保存详情页
     */
    @RequestMapping(value = "save")
    @ResponseBody
    public ResponseEntity<String> save(@RequestParam(value = "param", required = true) String param, HttpServletRequest httpServletRequest) {
        logger.info("AdPublishConditionController save() begin.");
        ErrorType errorType = null;
        Map<String, Object> data = null;
        try {
            User user = (User) httpServletRequest.getSession().getAttribute("user");
            /**
             * 如果保存的用户不是 admin，需要换成 admin 的ticket ，保证这个投放控制是admin修改的
             * 否则会规则引擎，数据抽取多个的地方，无法根据企业查询到admin的投放控制，也无法获得单价等控制信息。
             * 这只是个过渡方案，如果下次还要改这块来兼容其它功能，请重新考虑权限这块的设计吧，改动的地方会很多
             * good lucky boy，by hunk 16/11 2015
             */
//            User admin = userService.getAdminUserByCurrentUser(user.getTicket());
            AdPublishConditionDetailParam par = JSON.parseObject(param, AdPublishConditionDetailParam.class);
            Map<String, Long> priceLimitParam = par.getPriceLimit();
            if (par != null & priceLimitParam != null & par.getPageId() != null) {
                //conditionId 空则是新增， 有id则是更新
                String key = "condition_" + user.getTicket();
                if (redisClient.hasKey(key)) {
                    errorType = ErrorType.PUBLISH_CONDITION_FLAG;
                } else {
                    try {
                        redisClient.set(key, 1);
                        Long conditionId;
                        if (par.getConditionId() != null) {
                            adPublishConditionService.updateDetail(par, user.getTicket());
                            conditionId = par.getConditionId();
                        } else {
                            conditionId = adPublishConditionService.saveDetail(par, user.getTicket());
                        }
                        data = new HashMap<>();
                        data.put("conditionId", conditionId);
                    } catch (Exception e) {
                        errorType = ErrorType.PUBLISH_CONDITION_FAIL;
                        logger.error("AdPublishConditionController save() Error", e);
                    } finally {
                        redisClient.delete(key);
                    }
                }
            } else {
                errorType = ErrorType.PARAM_EXCEPTION;
            }
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("AdPublishConditionController save() end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSON(outputResult).toString());
    }

    /**
     * 更改投放状态：设置投放状态
     */
    @RequestMapping(value = "updateStatus")
    @ResponseBody
    public ResponseEntity<String> updateStatus(@RequestParam(value = "param", required = true) String param, HttpServletRequest httpServletRequest) {
        logger.info("AdPublishConditionController updateStatus() begin.");
        ErrorType errorType = null;
        AdPublishConditionResult data = null;
        try {
            User user = (User) httpServletRequest.getSession().getAttribute("user");
            UpdateStatusParam updateStatusParam = JSON.parseObject(param, UpdateStatusParam.class);
//            User userAdmin = userService.getAdminUserByCurrentUser(user.getTicket());
//            String userAdminId = "";
//            if(userAdmin != null){
//                userAdminId = userAdmin.getTicket();
//            }
            AdPublishCondition con = adPublishConditionService.updateStatus(user.getTicket(), updateStatusParam.getId(), updateStatusParam.getStatus());
            if (con != null) {
                data = new AdPublishConditionResult();
                data.setId(con.getId());
                data.setStatus(con.getStatus() ? 1 : 0);
            }
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("AdPublishConditionController updateStatus() end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSON(outputResult).toString());
    }

    /**
     * 根据应用id获取账户
     */
    @RequestMapping(value = "getAccounts")
    @ResponseBody
    public ResponseEntity<String> getAccounts(@RequestParam(value = "param", required = true) String param, HttpServletRequest httpServletRequest) {
        logger.info("AdPublishConditionController getAccounts() begin.");
        ErrorType errorType = null;
        List<EntrustAccountVo> data = new ArrayList<>();
        try {
            User user = (User) httpServletRequest.getSession().getAttribute("user");
            AccountFromConnParam accountFromConnParam = JSON.parseObject(param, AccountFromConnParam.class);
            List<EntrustAccountExt> entrustAccounts;
            if(accountFromConnParam != null && accountFromConnParam.isOutLink())
            {
                entrustAccounts = entrustAccountService.findEntrustAccountsByUserId(user.getTicket());
            }
            else
            {
                entrustAccounts = entrustAccountService.findEntrustAccountsByfbConnectionObjectIdAndUserId(accountFromConnParam.getConnObjId(), user.getTicket());
            }
            Set<Long> accountIds = new HashSet<>();
            //在这里 去个重
            if (!CollectionUtils.isEmpty(entrustAccounts)) {
                EntrustAccountExt ad = null;
                int size = entrustAccounts.size();
                for (int i = size-1;i>=0;i--) {
                    ad = entrustAccounts.get(i);
                    if(!accountIds.contains(ad.getFbAccountId())){
                        accountIds.add(ad.getFbAccountId());
                    }else{
                        entrustAccounts.remove(i);
                    }
                }
            }
            if (ListUtil.isNotEmpty(entrustAccounts)) {
                data = getEntrustAccountVo(entrustAccounts);
            }
        } catch (Exception e) {
            errorType = ErrorType.INTERNAL_EXCEPTION;
            logger.error(e.getMessage(), e);
        }
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("AdPublishConditionController getAccounts() end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSON(outputResult).toString());
    }

    private List<EntrustAccountVo> getEntrustAccountVo(List<EntrustAccountExt> entrustAccounts) {
        List<EntrustAccountVo> voList = new ArrayList<>();
        EntrustAccountVo entrustAccountVo;
        for (EntrustAccountExt entrustAccount : entrustAccounts) {
            entrustAccountVo = new EntrustAccountVo();
            entrustAccountVo.setId(entrustAccount.getId());
            String displayName = entrustAccount.getEmail() != null ? entrustAccount.getEmail() : (entrustAccount.getName() != null ? entrustAccount.getName() : entrustAccount.getFbAccountId() + "");
            entrustAccountVo.setDisplayName(displayName);
            entrustAccountVo.setFbAccountId(entrustAccount.getFbAccountId());
            entrustAccountVo.setStatus(entrustAccount.getStatus());
            entrustAccountVo.setRole(entrustAccount.getRole());
            entrustAccountVo.setFbUserId(entrustAccount.getFbUserId());
            entrustAccountVo.setTimezone(entrustAccount.getTimezone());
            entrustAccountVo.setOffset(entrustAccount.getTimezoneOffset());
            voList.add(entrustAccountVo);
        }
        return voList;
    }

    /**
     * processHistoryDatas
     */
    @RequestMapping(value = "processHistoryDatas")
    @ResponseBody
    public ResponseEntity<String> processHistoryDatas() {
        logger.info("AdPublishConditionController processHistoryDatas() begin.");
        ErrorType errorType = null;
        Map<String, Object> data = adPublishConditionService.processHistoryDatas();
        OutputResult outputResult = ResponseUtils.bulidOutputResult(errorType, data);
        logger.info("AdPublishConditionController processHistoryDatas() end.");
        return ResponseUtils.returnJsonWithUTF8(JSON.toJSON(outputResult).toString());
    }
}
